package com.example.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.example.service.ActivitiService;

@Component
public class ActivitiServiceImpl implements ActivitiService{
	private static final Logger LOG = LoggerFactory.getLogger(ActivitiService.class);
	
    @Autowired
    private ProcessEngine processEngine;

//    @PostConstruct
//    private void init() {
//    	 Deployment deployment = processEngine.getRepositoryService().createDeployment().addClasspathResource("processes/wf01.bpmn").deploy();
//         LOG.info("Bpmn file  has been successfully deployed, deploymentId = " + deployment.getId());
//    }
    
    /**
     * 部署一个流程
     *
     * @param bpmnName
     * @return
     */
    @Override
    public String deploy(String bpmnName) {
        Deployment deployment = processEngine.getRepositoryService().createDeployment().addClasspathResource(bpmnName).deploy();
        LOG.info("Bpmn file " + bpmnName + " has been successfully deployed, deploymentId = " + deployment.getId());
        return deployment.getId();
    }

    /**
     * 订单创建后，启动一个流程实例
     *
     * @param key      流程xml文件的id属性
     * @param orderId  订单id
     * @param username APP登陆用户名
     */
    @Override
    public void startProcess(String key, Long orderId, String username) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("orderId", orderId);
        variables.put("username", username);
        ProcessInstance instance = processEngine.getRuntimeService().startProcessInstanceByKey(key, variables);
        LOG.info("流程实例启动完成，流程id=" + instance.getId());
    }

    /**
     * APP工作流交互
     *
     * @param username app登陆用户名
     * @param orderId  订单id
     */
    @Override
    public void afterSubmit(String username, Long orderId) {
        List<Task> tasks = processEngine.getTaskService().createTaskQuery().taskAssignee(username).list();
        for (Task task : tasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj || !orderId.equals(Long.valueOf(String.valueOf(orderIdObj)))) {
                continue;
            }
            processEngine.getTaskService().complete(task.getId());
            break;
        }
    }
    @Override
    public int approval(List<String> groupNames, String username, Long orderId, Boolean result) {
        List<Task> groupTasks = getGroupTasks(groupNames);
        List<Task> tasks = processEngine.getTaskService().createTaskQuery().taskAssignee(username).list();
        if (groupTasks.size() > 0) {
            tasks.addAll(groupTasks);
        }
        if (tasks.size() == 0) {
            LOG.error("订单id为:" + orderId + "已经被其它用户接单");
            return 0;
        }
        for (Task task : tasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj || !orderId.equals(Long.valueOf(String.valueOf(orderIdObj)))) {
                continue;
            }
            processEngine.getTaskService().claim(task.getId(), username);
            processEngine.getTaskService().setVariable(task.getId(), "result", result);
            processEngine.getTaskService().complete(task.getId());
            break;
        }
        return 1;
    }

    private List<Task> getGroupTasks(List<String> groupNames) {
        List<Task> tasks = new ArrayList<>();
        for (String groupName : groupNames) {
            List<Task> groupTasks = processEngine.getTaskService().createTaskQuery().taskCandidateGroup(groupName).list();
            if (null != groupTasks && groupTasks.size() > 0) {
                tasks.addAll(groupTasks);
            }
        }
        return tasks;
    }

    /**
     * 获取待处理订单id集合
     *
     * @param usernameList 当前用户所有岗位下的所有用户
     * @param groupNames   流程角色
     * @param currentUser  当前用户
     * @return
     */
    @Override
    public Map<Long, Integer> pendingOrderIds(List<String> usernameList, List<String> groupNames, String currentUser) {
        List<Task> tasks = getGroupTasks(groupNames);
        Map<Long, Integer> orderIds = new LinkedHashMap<>();
        // 待领取的任务
        for (Task task : tasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj) {
                continue;
            }
            orderIds.put(Long.valueOf(String.valueOf(orderIdObj)), 0);
        }
        List<Task> myTasks = processEngine.getTaskService().createTaskQuery().taskAssignee(currentUser).list();
        // 当前用户的任务
        for (Task task : myTasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj) {
                continue;
            }
            orderIds.put(Long.valueOf(String.valueOf(orderIdObj)), 1);
        }
        usernameList.removeIf(e -> e.equals(currentUser));
        List<Task> personalTasks = new ArrayList<>();
        // 其它用户的任务
        for (String username : usernameList) {
            List<Task> list = processEngine.getTaskService().createTaskQuery().taskAssignee(username).list();
            if (null != list && list.size() > 0) {
                personalTasks.addAll(list);
            }
        }
        for (Task task : personalTasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj) {
                continue;
            }
            orderIds.put(Long.valueOf(String.valueOf(orderIdObj)), 2);
        }
        return orderIds;
    }

    /**
     * 接单（将流程任务划到自己名下）
     *
     * @param username   用户名
     * @param groupNames 流程角色
     * @param orderId    订单id
     * @return 0: 其他用户已经接单 1. 处理成功
     */
    @Override
    public int claim(String username, List<String> groupNames, Long orderId) {
        List<Task> tasks = getGroupTasks(groupNames);
        if (tasks.size() == 0) {
            LOG.error("订单id为:" + orderId + "已经被其它用户接单");
            return 0;
        }
        for (Task task : tasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj || !orderId.equals(Long.valueOf(String.valueOf(orderIdObj)))) {
                continue;
            }
            processEngine.getTaskService().claim(task.getId(), username);
            break;
        }
        return 1;
    }

    /**
     * 获取已处理订单id
     *
     * @param username     用户名
     * @param variableName 变量名
     * @return
     */
    @Override
    public List<Long> processedOrderIds(String username, String variableName) {
        List<Long> idList = new ArrayList<>();
        // 获取当前用户已完成的userTask
        List<HistoricTaskInstance> instances = processEngine.getHistoryService().createHistoricTaskInstanceQuery().taskAssignee(username).finished().list();
        if (null == instances || instances.size() == 0) {
            return idList;
        }
        for (HistoricTaskInstance instance : instances) {
            List<HistoricVariableInstance> variables = processEngine.getHistoryService().createHistoricVariableInstanceQuery().processInstanceId(instance.getProcessInstanceId()).list();
            if (null == variables || variables.size() == 0) {
                continue;
            }
            for (HistoricVariableInstance variable : variables) {
                if (variableName.equals(variable.getVariableName())) {
                    Long orderId = Long.valueOf(String.valueOf(variable.getValue()));
                    if (!idList.contains(orderId)) {
                        idList.add(orderId);
                    }
                }
            }
        }
        return idList;
    }

    @Override
    public boolean isOwner(Long orderId, String currentUser) {
        boolean isOwner = false;
        List<Task> myTasks = processEngine.getTaskService().createTaskQuery().taskAssignee(currentUser).list();
        // 当前用户的任务
        for (Task task : myTasks) {
            Object orderIdObj = processEngine.getTaskService().getVariable(task.getId(), "orderId");
            if (null == orderIdObj) {
                continue;
            }
            if (orderId.equals(Long.valueOf(String.valueOf(orderIdObj)))) {
                isOwner = true;
                break;
            }
        }
        return isOwner;
    }
}
